/*
hmi_x5.c
offer hmi uart screen control and recive massage api realize 
designed by lunanting


--------------------------
create file
2022-03-03 14:26:55
--------------------------
*/

#include "hmi_x5.h"
#include "bsp.h"
#include "aos/hal/uart.h"
#include "aos/kernel.h"


static char end[3]={0xff,0xff,0xff};
void xp_hmi_recive(void *arg);

/*
init hmi on a uart port
param:
    port: uart port
    speed: uart baud speed
    rec_deal: regist recive msg from hmi deal api,NULL= not regist 
return: the hmi device object
    NULL=init fail
    
*/
HMI *xp_hmi_init(int port,int speed,void (*rec_deal)(char *,int)){
    int sta=0;
    uart_dev_t *uart;
    HMI *hmi;
    char *err="";
    
    if(port<0||port>10){
        err="uart port set fault !";
        goto FAIL;
    }
    if(speed<2400||speed>10000000){
        err="uart baud speed set fault !";
        goto FAIL;
    }
    

    uart=(uart_dev_t *)malloc(sizeof(uart_dev_t));
    memset(uart,0,sizeof(uart_dev_t));
    hmi=(HMI *)malloc(sizeof(HMI));
    memset(hmi,0,sizeof(HMI));

    hmi->port=port;
    hmi->speed=speed;
    hmi->uart=(void *)uart;

    uart->port=port;
    uart->config.baud_rate=speed;
    uart->config.data_width=DATA_WIDTH_8BIT;
    uart->config.parity=NO_PARITY;
    uart->config.stop_bits=STOP_BITS_1;
    uart->config.flow_control=FLOW_CONTROL_DISABLED;
    uart->config.mode=MODE_TX_RX;

    sta=hal_uart_init(uart);
    if(sta!=0){
        err="uart init fail !";
        goto FAIL;
    }
    
    if(rec_deal!=NULL){
        hmi->rec_deal=rec_deal;
    }

    sprintf(hmi->rec_task,"hmi-rec%d",port);
    aos_task_new(hmi->rec_task,xp_hmi_recive,hmi,3000);

    hmi->init=1;
    println("hmi device init success. on %d uart %d baud.",port,speed);
    return hmi;
FAIL:
    perr("hmi device init fail !, %s. uart %d port %d baud.",err,port,speed);
    return NULL;
}






/*
deinit hmi device
param:
    hmi: hmi object
return:
    0=success
*/
int xp_hmi_deinit(HMI *hmi){
    char *err="";

    if(hmi==NULL){
        err="hmi point NULL";
        goto FAIL;
    }
    if(hmi->uart!=NULL){
        hal_uart_finalize((uart_dev_t *)hmi->uart);
        free(hmi->uart);
    }
    aos_task_delete(hmi->rec_task);
    free(hmi);
    println("deinit hmi success !");
    return 0;
FAIL:
    perr("deinit hmi fail. %s.");
    return -1;
}


/*
send cmd or msg to hmi screen
param:
    hmi: hmi screen object
    msg: send msg or cmd
return:
    0=success
*/
int xp_hmi_send(HMI *hmi,char *msg){
    int sta=0;
    uart_dev_t *uart=(uart_dev_t *)hmi->uart;
    println("hmi send: %s.",msg);
    sta=hal_uart_send(uart,msg,strlen(msg),100);
    sta|=hal_uart_send(uart, end,3,100);
    return sta;
}


/*
recive msg from hmi screen and deal thread
*/
void xp_hmi_recive(void *arg){
    char rec_buf[100]={0};
    u32 rec_len=0;
    HMI *hmi=(HMI *)arg;
    uart_dev_t *uart=(uart_dev_t *)hmi->uart;
    int value=0;

    while(1){
        memset(rec_buf,0,rec_len);
        rec_len=0;
        hal_uart_recv_II(uart,rec_buf,99,&rec_len,100);
        if(rec_len==0){
            continue;
        }

        if(hmi->rec_deal!=NULL){
            hmi->rec.rec_flag=1;
            if(rec_buf[rec_len-1]==0xff){
                if(rec_buf[0]==0x70){
                    rec_buf[0]=0;
                    hmi->rec.rec_type=0x70;
                    memcpy(value,rec_buf+1,4);
                    hmi->rec.data=value;
                }
                else if(rec_buf[0]==0x71){
                    rec_buf[0]=0;
                    hmi->rec.rec_type=0x71;
                    memcpy(hmi->rec.msg,rec_buf+1,rec_len-4);
                }
                else if(rec_buf[0]==0x68){

                }
                else if(rec_buf[0]<0x25){
                    if(rec_buf[0]==0x01){
                        hmi->rec.rec_flag=0;
                        continue;
                    }
                    hmi->rec.rec_type=-1;
                    hmi->rec.err_code=rec_buf[0];
                }
            }
            else{
                hmi->rec.rec_type=0;
                hmi->rec_deal(rec_buf,rec_len);
            }
        }
        else{
            if(rec_buf[rec_len-1]!=0xff){
                println("rec from hmi screen: %s.",rec_buf);
            }
            else if(rec_buf[0]==0x70){
                rec_buf[-3]=0;
                println("rec from hmi screen get: %s.",rec_buf+1);
            }
            else if(rec_buf[0]==0x71){
                memset(value,rec_buf+1,4);
                println("rec from hmi screen get: %d.",value);
            }
            else if(rec_buf[0]==0x68){
                println("hmi sleep mode touch event !");
            }
            else if(rec_buf[0]<0x25){
                println("rec from hmi screen err: %X, len=%d.",rec_buf[0],rec_len-3);
            }
        }
    }
}

/*
regist recive deal api
param:
    hmi: hmi screen object
    rec_deal: custmer deal api
return:
    0=success
*/
int xp_hmi_recDealAPI_regist(HMI *hmi,void (*rec_deal)(char*,int)){
    if(hmi==NULL)return -1;
    if(rec_deal==NULL)return -2;
    hmi->rec_deal=rec_deal;
    return 0;
}




/*****************************debug************************************/
static HMI *demo;
static char demo_buf[100];
static int xp_hmi_debug(char *type,char *fun,char *param);
/*
init a hmi screen demo
*/
HMI *xp_hmi_demo(int port,int speed){
    demo=xp_hmi_init(port,speed,NULL);
    if(demo!=NULL){
        xp_cli_debug_add(xp_hmi_debug);
        return demo;
    }
    else{
        return NULL;
    }
}





static int xp_hmi_debug(char *type,char *fun,char *param){
    if(strcmp(type,"hmi")!=0)return 0;
    if(strlen(param)>0){
        sprintf(demo_buf,"%s %s",fun,param);
    }
    else{
        sprintf(demo_buf,"%s",fun);
    }
    xp_hmi_send(demo,demo_buf);

    return 1;
}

//end of the file
